<template>
	<view>
		<view class="content" id="content" @touchstart="hideDrawer">
			<scroll-view id="scrollview" @scroll="scroll" class="msg-list" :class="{'chat-h':popupLayerClass === 'showLayer'}" scroll-y="true"
			 :scroll-with-animation="scrollAnimation" :scroll-top="scrollTop" :scroll-into-view="scrollToView" @scrolltoupper="loadHistory"
			 upper-threshold="50">
				
				<view v-if="!loading"><u-loading mode="flower"></u-loading></view>
				<view id="msglistview" class="row" v-for="(row,index) in msgList" :key="index" :id="'msg'+row.id">
					
					<!-- 系统通知的消息 -->
					<system-bubble :row="row"></system-bubble>
					
					<!-- 别人发出的消息 -->
					<left-bubble @oLf="oLf" @sendMsg="sendMsg" :lClickId="lClickId" :row="row" :playMsgId="playMsgid" :index="index"
					 @openPacket="openPacket" @deleteMethod="deleteMethod"></left-bubble>
					
					<!-- 自己发出的消息 -->
					<right-bubble @deleteMethod="deleteMethod" @sendMsg="sendMsg" @oRt="oRt" :rClickId="rClickId"
					  :index="index" @openPacket="openPacket" :row="row" :playMsgid="playMsgid"></right-bubble>
				</view>
			</scroll-view>
		</view>
		
		<!-- 抽屉栏 -->
		<im-drawer @addEmoji="addEmoji" @sendMsg="sendMsg" @getImage="getImage"
				   @redShow="redFlag = true" :hideMore="hideMore" :hideEmoji="hideEmoji" :popupLayerClass="popupLayerClass"></im-drawer>
		
		<!-- 底部输入框 -->
		<footer-input @textMsgFunc="textMsgFunc" @switchVoice="switchVoice" @chooseEmoji="chooseEmoji" @sendMsg="sendMsg"
					  @showMore="showMore" @hideDrawer="hideDrawer" @openDrawer="openDrawer"
		 :disabledSay="disabledSay" :textMsg2="textMsg" :popupLayerClass="popupLayerClass"
					  :inputOffsetBottom="inputOffsetBottom" :isVoice="isVoice"></footer-input>
		
		<!-- 红包卡片弹窗 -->
		<red-card @robRed="robRed" @closeRed="closeRed" :winState="winState"></red-card>
		
		<!-- 发红包弹窗 -->
		<u-popup v-model="redFlag" mode="bottom" length="50%">
			<red-envelope @sendRedPacket="sendRedPacket">
			</red-envelope>
		</u-popup>
	</view>
</template>
<script>
	import ImDrawer from '@/components/chat/im-drawer.vue'
	import RedCard from '@/components/chat/red-card.vue'
	import RedEnvelope from "@/components/redenvelope"
	import ImgCache from '@/components/img-cache/img-cache.vue'
	import RightBubble from '@/components/chat/right-bubble.vue'
	import LeftBubble from '@/components/chat/left-bubble.vue'
	import FooterInput from '@/components/chat/footer-input.vue'
	import SystemBubble from '@/components/chat/system-bubble.vue'
	import { queryData, upData, initData, upRedData, upCanceData } from '../../util/dbStorage.js'
	import { emojiList } from "@/static/emoji/emoji.js"
	export default {
		components: {
			ImDrawer,
			RedCard,
			ImgCache,
			RightBubble,
			LeftBubble,
			SystemBubble,
			RedEnvelope,
			FooterInput
		},
		data() {
			return {
				loading: true, //标识是否正在获取数据
				textMsg: '',
				redFlag: false,
				rClickId:0,
				lClickId:0,
				pageNum:1,
				disabledSay:0,
				old: {
					scrollTop: 0
				},
				scrollTop:0,
				scrollToView:'',
				scrollAnimation:false,
				inputOffsetBottom: 0,
				viewOffsetBottom: 0, 
				msgList:[],
				isVoice:false,
				playMsgid:null,
				popupLayerClass:'',
				hideMore:true,
				hideEmoji:true,
				winState:'',
				message:{},
			};
		},
		//头部按钮监听
		onNavigationBarButtonTap({ index }) {
			if (index == 0) {
				let url = this.chatObj.chatType==1?'groupDetail':'userDetail'
				this.$u.route({
					url: 'pages/chat/' + url
				});
				//用户详情 设置
			} else if (index == 1) {
				//返回按钮
				this.$u.route({
					type: 'switchTab',
					url: 'pages/home/home'
				});
			}
		},
		onShow(){
			this.disabledSay = 0
			this.scrollTop = 9999999;
			this.sendMsg(0,'');
			this.getMsgItem();
			this.openConver();
			this.hideDrawer();
		},
		onReady() {
            // #ifdef H5
            const icon = document.getElementsByClassName('uni-page-head-btn')[0];
            icon.style.display = 'none';
            // #endif
			uni.setNavigationBarTitle({
				title: this.chatObj.chatName
			});
			//h5暂不支持键盘的高度监听
			uni.onKeyboardHeightChange(res => {
				this.inputOffsetBottom = res.height;
				this.viewOffsetBottom = res.height + uni.upx2px(100);
				if (res.height == 0) {
					// #ifndef MP-WEIXIN
					//this.showInput = false;
					// #endif
				}
			});
		},
		watch: {
			inputOffsetBottom: {
				handler(val) {
					if (val != 0) {
						this.$nextTick(() => {
							// #ifndef MP-WEIXIN || H5
							// #endif
						});
					}
				}
			}
		},
		methods:{
			scroll: function(e) {
				this.old.scrollTop = e.detail.scrollTop;
			},
			goTop: function(e) {
				this.scrollTop = this.old.scrollTop
				this.$nextTick(function() {
					this.scrollTop = 0
				});
				uni.showToast({
					icon:"none",
					title:"纵向滚动 scrollTop 值已被修改为 0"
				})
			},
			textMsgFunc(t){
				this.textMsg = t;
			},
			// 切换语音/文字输入
			switchVoice(){
				this.hideDrawer();
				this.isVoice = this.isVoice?false:true;
			},
			//添加表情
			addEmoji(em, del){
				//判断删除按钮
				if(del){
				  var str;
				  var msglen = this.textMsg.length - 1;
				  let start = this.textMsg.lastIndexOf("[");
				  let end = this.textMsg.lastIndexOf("]");
				  let len = end - start;
				  if(end != -1 && end === msglen && len >= 2 && len <= 4){
					    // 表情字符
						str = this.textMsg.slice(0, start);
					}else{
						// 普通键盘输入汉字 或者字符
						str = this.textMsg.slice(0, msglen);
					}
					
					this.textMsg = str
					return;
				}
			    this.textMsg += em.emojiItem.alt;
			},
			oLf(row){
				this.lClickId = row.id;
			},
			oRt(row){
				this.rClickId = row.id;
			},
			// 关闭红包弹窗
			closeRed(){
				this.winState = 'hide';
				setTimeout(()=>{
					this.winState = '';
				},200)
			},
			// 打开红包
			openPacket(msg){
				this.winState = 'show'
				this.message = msg
				this.$u.vuex('packet',this.red_process(msg.msgContext));
			},
			// 开始抢红包
			robRed(){
				console.log(1);
				this.sendMsg(8, this.message.id);
			},
			//处理红包数据
			red_process(msgContext){
				let packets = JSON.parse(msgContext).Packets;
				let msg = {
						description:'红包异常',
						money:0,
						number:0,
						userAvatar:'defalut.jpg',
					}
				if(packets===undefined)
					return msg;
				return packets[0];
			},
			hideRed(){
				this.redFlag = false;
			},
			//更多功能(点击+弹出)
			showMore(){
				this.isVoice = false;
				this.hideEmoji = true;
				if(this.hideMore){
					this.hideMore = false;
					this.openDrawer();
				}else{
					this.hideDrawer();
				}
			},
			// 打开抽屉
			openDrawer(){
				this.popupLayerClass = 'showLayer';
				this.scrollAnimation = false
				this.$nextTick(() => {
					if(this.msgList.length>0){
						this.scrollToView = 'msg' + this.msgList[this.msgList.length-1].id
						this.scrollAnimation = true;
					}
				});
			},
			// 隐藏抽屉
			hideDrawer(){
				this.popupLayerClass = '';
				setTimeout(()=>{
					this.hideMore = true;
					this.hideEmoji = true;
					this.rClickId = 0;
					this.lClickId = 0;
					uni.hideKeyboard();
				},150);
			},
			// 置底
			scrollToBottom(t) {
					let that = this
					let query = uni.createSelectorQuery()
					query.select('#scrollview').boundingClientRect()
					query.select('#msglistview').boundingClientRect()
					query.exec((res) => {
						if(res[1].height > res[0].height){
							that.scrollTop = res[1].height - res[0].height
						}
					})
			},
			//删除
			deleteMethod(id,index){
				this.msgList.splice(index,1);
			},
			//处理红包数据
			red_process(msgContext){
				let packets = JSON.parse(msgContext).Packets;
				let msg = {
					description:'红包异常',
					money:0,
					number:0,
					userAvatar:'defalut.jpg',
					surplusMoney:0,
					Records:[]
				}
				if(packets==undefined){
					return msg;
				}
				if(packets.length==0){
					return msg;
				}
				return packets[0];
			},
			//发送红包
			sendRedPacket(packet){
				if(this.chatObj.chatType==0){
					uni.showToast({
						title:'暂不支持私发红包'
					})
					return;
				}
				this.sendMsg(7, packet)
				this.redFlag = false;
			},
			//暂时不适配微信小程序，正在解决此bug
			bindScroll(sel, duration = 0) {
				uni.createSelectorQuery()
					.select('#content')
					.boundingClientRect(data => {
						console.log(data)
						//最外层盒子节点
						uni.createSelectorQuery()
							.select(sel)
							.boundingClientRect(res => {
								if (!res) return;
								//选中的节点
								let windowHeight = 0;
								uni.getSystemInfo({
									success: system => {
										windowHeight = system.windowHeight;
									}
								});
								const inputKeyBoardHeight = uni.upx2px(100) + this.inputOffsetBottom; 
								//input输入框和键盘的高度
								const contentHeight = windowHeight - inputKeyBoardHeight; 
								//可视内容的高度（除去input输入框和键盘）
								let scrollTop = 0;
								scrollTop = res.top - data.top - contentHeight + res.height; 
								//滚动到实际距离是元素距离顶部的距离减去最外层盒子的滚动距离再减去可视内容的高度然后再加上此元素的高度
								uni.pageScrollTo({ duration, scrollTop });
							})
							.exec();
					})
					.exec();
			},

			//监听输入框
			Input(e){
				if(this.textMsg.indexOf('@')!=-1){
				  if (this.chatObj.chatType==1){
					  this.$u.route({
					  	url:'pages/chat/remind',
					  	params:{ msg :this.textMsg }
					  });	
				  }
				}
			},
			//消费消息
			openConver () {
			  let _this = this
			  this.$socket.openChat(this.chatObj.chatId, this.userData.user.operId, this.chatObj.chatType, res => {
				if (res.success) {
				  if (_this.chatObj.chatType == 1) {
					if (res.groupUser === undefined) {
					  _this.disabledSay = 1
					} else {
					  _this.disabledSay = res.groupUser.status
					}
				  }
				}
			  })
			},
			// localStorage版本获取消息列表
			getMsgItem(){
				if(this.chatObj.chatType==0){
					this.scrollAnimation = false;
					 this.$socket.queryFriendMessages(this.chatObj.chatId, this.userData.user.operId,1, (res) => {
						 this.msgList = res.response.data;
						 this.scrollTop = 9999;
						 this.scrollAnimation = true;
					 });
				}else {
                    this.scrollAnimation = false;
                    queryData(this.chatObj.chatId).then(res=>{
                        this.msgList = res;
                        this.$nextTick(function() {
                            this.scrollTop = 9999;
                            this.scrollAnimation = true;
                        });
                    });
				}
			},
			// sqlite版本获取消息列表
			getMsgList2(){
				this.scrollAnimation = false;
				selectMsgSQL(this.chatObj.chatId).then(res=>{
					this.msgList = res
					this.$nextTick(function() {
						this.scrollTop = 9999;
						this.$nextTick(function() {
							this.scrollAnimation = true;
						});
					});
				});
			},
			//触发滑动到顶部(加载历史信息记录)
			loadHistory(e){
			if (!this.loading) {
				return;
			}
			this.loading = false;
			this.scrollAnimation = false;
			
			//关闭滑动动画
			let arr = ['queryFriendMessages','queryGroupMessages'];
			let i = this.chatObj.chatType
			  this.$socket[arr[i]](this.chatObj.chatId, this.userData.user.operId, this.pageNum, res => { 
				  let message = res.response.data;
				  if(message.length>0){
					  message.forEach(m=>{
						  if (!this.msgList.map(v => v.id).includes(m.id)) {
							this.msgList.push(m)
						  }  
					  })
					this.msgList.sort((a, b) => { return a.id - b.id })
					this.$nextTick(() => {
						this.scrollAnimation = true;
						this.loading = true;
						this.pageNum++
					});
				  }
				});
			},
			//处理图片尺寸，如果不处理宽高，新进入页面加载图片时候会闪
			setPicSize(content){
				// 让图片最长边等于设置的最大长度，短边等比例缩小，图片控件真实改变，区别于aspectFit方式。
				let maxW = uni.upx2px(350);//350是定义消息图片最大宽度
				let maxH = uni.upx2px(350);//350是定义消息图片最大高度
				if(content.w>maxW||content.h>maxH){
					let scale = content.w/content.h;
					content.w = scale>1?maxW:maxH*scale;
					content.h = scale>1?maxW/scale:maxH;
				}
				return content;
			},
			
			// 选择图片发送
			chooseImage(){
				this.getImage('album');
			},
			//拍照发送
			camera(){
			  this.getImage('camera');
			},
			//发红包
			handRedEnvelopes(){
			  this.hideDrawer();
			},
			//选照片 or 拍照
			getImage(type){
				let that=this;
				this.hideDrawer();
				uni.chooseImage({
					sourceType:[type],
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					success: (res)=>{
						for(let i=0;i<res.tempFilePaths.length;i++){
							uni.getImageInfo({
								src: res.tempFilePaths[i],
								success: (image)=>{
									  uni.uploadFile({
									            url: this.$uploadUrl, //仅为示例，非真实的接口地址
									            filePath: res.tempFilePaths[i],
									          header: {
											   'merchcode':'md5'
											   },
											   name: 'file',
											   formData: {
											       'user': 'test'
											   },
											     success: (res) => {
													 let data = JSON.parse(res.data)
												     this.sendMsg(1, data.data)
									            }
									   });
								}
							});
						}
					}
				});
			},
			// 选择表情
			chooseEmoji(){
				this.hideMore = true;
				if(this.hideEmoji){
					this.hideEmoji = false;
					this.openDrawer();
				}else{
					this.hideDrawer();
				}
			},
			//发送消息
			sendMsg (msgType, text) {
			 
			 if (this.disabledSay == 1) {
				 uni.showToast({
				 	title:'你已经被管理员禁言'
				 });
				 return;
			 }
			 
			 if(text!=''){
				 this.$socket.createChatList(this.userData.user.operId, this.chatObj.chatId, text, msgType, res => {});
			 }
			 
			  let arr = ['send2Friend','send2Group'];
			  let _this = this;
			  this.scrollAnimation = false;
			  
			  this.$socket[arr[this.chatObj.chatType]](this.chatObj.chatId, this.userData.user.operId, text, msgType, res => {
				if (res.success) {
					if (res.response!==undefined) {
						const data = res.response.data
						if(res.msgType===8){
							_this.envelope(res);
						}else if(res.msgType===6){
							_this.rollBack(res);
						}else {
							if(_this.chatObj.chatType===1){
								if(data!==undefined){
									if (data.groupId === this.chatObj.chatId) {
										_this.addMsg(data);
										uni.vibrateLong();
									}
									upData(data, _this.chatObj.chatId);
								}
							}else {
								if(data!==undefined){
									if(data.sendUid==this.chatObj.chatId||data.sendUid==this.userData.user.operId){
										_this.addMsg(data);
										uni.vibrateLong();
									}
								}
								
							}
						}
					}
				}
			  });
			  this.textMsg = ''
			},
			// 接受消息(筛选处理)
			addMsg(msg){
				// 用户消息
				switch (msg.msgType){
					case 0:
						this.addTextMsg(msg);
						break;
					case 1:
						this.addImgMsg(msg);
						break;
					case 3:
						this.addVoiceMsg(msg);
						break;
					case 7:
						this.addEnvelopeMsg(msg);
						break;
					default:
				}
				
				this.$nextTick(() => {
					this.scrollTop = 9999;
					this.scrollToView = 'msg' + this.msgList[this.msgList.length-1].id
					this.scrollAnimation = true;
				});
			},
			//撤销
			rollBack(res){
				if(this.chatObj.chatType==0){
					if (res.chatId != undefined && res.message == undefined) {
					  for(var index in this.msgList){
						if(this.msgList[index].id==res.chatId){
							this.msgList.splice(index,1);
							upCanceData(res.chatId,this.chatObj.chatId,this.msgList[index]);
						}
					  }
					}
				}else {
					if (res.msgId != undefined && res.message == undefined) {
					  for(var index in this.msgList){
						if(this.msgList[index].id==res.msgId){
							this.msgList.splice(index,1);
							upCanceData(res.msgId,this.chatObj.chatId,this.msgList[index]);
						}
					  }
					}
				}
				
			},
			// 红包
			envelope(res){
				if (res.msgId != undefined && res.message != undefined) {
					this.$u.vuex('packet',this.red_process(res.message));
					for(var index in this.msgList){
						if(this.msgList[index].id==res.msgId){
							this.msgList[index].msgContext = res.message;
						}
					}
					upRedData(res.msgId,this.chatObj.chatId,res.message);
				}
			},
			// 添加文字消息到列表
            addTextMsg(msg){
                this.msgList.push(msg);
            },
            // 添加语音消息到列表
            addVoiceMsg(msg){
                this.msgList.push(msg);
            },
            // 添加图片消息到列表
            addImgMsg(msg){
                this.msgList.push(msg);
            },
            addEnvelopeMsg(msg){
                this.msgList.push(msg);
            },
            // 添加系统文字消息到列表
            addSystemTextMsg(msg){
                this.msgList.push(msg);
            },
            // 添加系统红包消息到列表
            addSystemRedEnvelopeMsg(msg){
                this.msgList.push(msg);
            },
			discard(){
				return;
			},
		}
	}
</script>
<style lang="scss">
	@import "./style.scss";
</style>
